home *** CD-ROM | disk | FTP | other *** search
- (*********************************************************************
- * *** HAPPy P-code Interpreter for HAPPy Version 0.3 *** *
- * *
- * HAPPyのサンプルプログラム *
- * (作者 浅野比富美 Public Domain Software) *
- *********************************************************************)
-
- (*
- HPASM3.PASをコンパイルしてできるアセンブラで作成したP-codeオブジェクトを
- 解釈実行します。
-
- const,type,var の各部にある * 印がついたものは、アセンブラ、インタプリタ
- 共通の定義項目です。
- *)
-
- program HAPPyPcodeInterpreter(pCode,pConst,input,output) ;
-
- label 9999 ; { プログラム出口 }
-
- const
-
- {*} SetLow = 0 ; { HAPPy 集合要素順序数 下限値 }
- {*} SetHigh = 31 ; { HAPPy 集合要素順序数 上限値 }
- {*} MaxCode = 1000 ; { コード部上限 }
- {*} MaxData = 3000 ; { データ部上限 }
- NilValue = -1 ; { ポインタ nil値 }
-
- (***** データ種別番号 *****)
- {*} Inte = 1 ; { 整数データ }
- {*} Reals = 2 ; { 実数データ }
- {*} Chars = 3 ; { 文字データ }
- {*} Bool = 4 ; { 論理データ }
- {*} Sets = 5 ; { 集合データ }
- {*} datAd = 6 ; { データ部アドレス }
- {*} codAd = 7 ; { コード部アドレス }
- {*} Multi = 8 ; { 列データ }
- {*} Nils = 9 ; { nilデータ }
- {*} Proc = 10 ; { 手続き }
-
- type
-
- (*** P-code命令の定義 ***)
- {*} opType = { アルファベット順に並べること }
- ( iABI, { absolute integers }
- iABR, { absolute reals }
- iADI, { add integers }
- iADR, { add reals }
- iAND, { and operator }
- iATN, { arctan standard function }
- iBAS, { load base mark address }
- iCHK, { check value between bounds }
- iCHR, { chr standard function }
- iCKA, { check address }
- iCKS, { check set (P-codeソース上に現れない) }
- iCOS, { cos standard function }
- iCUI, { call user procedure indirect }
- iCUP, { call user procedure }
- iDEC, { decrement }
- iDIF, { difference set }
- iDIS, { dispose standard procedure }
- iDVI, { divide integers }
- iDVR, { divide reals }
- iEJP, { extra block jump }
- iENT, { enter procedure or function }
- iEOF, { eof standard function }
- iEOL, { eoln standard function }
- iEQU, { equal operator }
- iEXP, { exp standard function }
- iFJP, { jump on false }
- iFLO, { float integer to real on sp-1 }
- iFLT, { float integer to real }
- iGEQ, { grater than equal operator }
- iGET, { get from not text } { not support }
- iGRT, { grater than operator }
- iINC, { increment }
- iIND, { indexed fetch }
- iINN, { in operator }
- iINT, { intersection set }
- iIOR, { or operator }
- iIXA, { indeced address }
- iLAO, { load base-level address }
- iLAP, { load address of procedure }
- iLCA, { load address of constant }
- iLDA, { load level p address }
- iLDC, { load constant }
- iLDO, { load contents of base-level address }
- iLEQ, { less than equal operator }
- iLES, { less than operator }
- iLOD, { load contents of address at level p }
- iLOG, { ln standard function }
- iMMS, { make multiple set }
- iMOD, { modulo operator }
- iMOV, { move }
- iMPI, { mulutiple integers }
- iMPR, { mulutiple reals }
- iMSI, { mark stack indirect }
- iMST, { mark stack }
- iNEQ, { not equal operator }
- iNEW, { new standard procedure }
- iNGI, { negative integers }
- iNGR, { negative reals }
- iNOT, { not operator }
- iNXT, { next to }
- iNXD, { next downto }
- iODD, { odd standard function }
- iORD, { ord standard function }
- iPGE, { page standard procedure }
- iPUT, { put from not text } { not support }
- iRDC, { read char }
- iRDI, { read integer }
- iRDR, { read real }
- iRET, { return from procedure or function }
- iRLN, { readln standard procedure }
- iROU, { round }
- iRST, { reset for not text } { not support }
- iRWT, { rewrite for not text } { not support }
- iSBI, { subtract integers }
- iSBR, { subtract reals }
- iSGS, { create singleton set }
- iSIN, { sin standard function }
- iSQI, { square integers }
- iSQR, { square reals }
- iSQT, { sqrt standard function }
- iSRO, { store at base-level address }
- iSTO, { store indirect }
- iSTP, { stop }
- iSTR, { store contents at address at level p }
- iTGT, { get from text }
- iTPT, { put from text }
- iTRA, { trace of execution }
- iTRC, { trunc standard function }
- iTRS, { reset for text file }
- iTRW, { rewrite for text file }
- iUJC, { check uncondition jump }
- iUJP, { uncondition jump }
- iUNI, { union set }
- iWLN, { writeln standard procedure }
- iWRB, { write boolean }
- iWRC, { write char }
- iWRF, { write real fix }
- iWRI, { write integer }
- iWRR, { write real }
- iWRS, { write string }
- iXJP, { indexed jump }
- iZZZ { 終わり }
- ) ;
-
- {*} codeRange = 0..MaxCode ; { コード部の添字範囲 }
- {*} dataRange = 0..MaxData ; { データ部の添字範囲 }
- {*} dataRange1 = -1..MaxData ; { データ部の添字範囲(-1を含む)}
- {*} setType = set of SetLow..SetHigh;{ 集合 (HAPPy要素順序数制限内)}
- {*} pType = 0..255 ; { p オペランドの型 }
-
- {*} codeType = record { コード部の中身 }
- op : opType ; { オペレーション }
- p : pType ; { p オペランド }
- q : integer { q オペランド }
- end ;
-
- {*} dataKind = Inte..CodAd ; { dataTypeに用いるもの}
- {*} dataType = record case dataKind of
- Inte : (vi : integer) ; { 整数型・列挙型データ }
- Reals : (vr : real) ; { 実数型データ }
- Chars : (vc : char) ; { 文字型データ }
- Bool : (vb : Boolean) ; { 論理型データ }
- Sets : (vs : setType) ; { 集合型データ }
- DatAd : (va : dataRange1) ; { データ部アドレス }
- CodAd : (vp : codeRange) { コード部アドレス }
- end ;
-
- var
-
- {*} pcode : file of codeType ; { P-code コードファイル }
- {*} pConst : file of dataType ; { P-code 定数ファイル }
-
- (*** P-code仮想計算機記憶装置 ***)
- {*} code : array[codeRange] of codeType ; { コード部格納エリア }
- {*} store : array[dataRange] of dataType ; { データ部格納エリア }
-
- (*** P-code仮想計算機レジスタ ***)
- pc : codeRange ; { プログラムカウンタ }
- mp : dataRange ; { スタック枠の始まりを保持する }
- np : dataRange ; { ヒープ領域の末尾を保持する }
- sp : dataRange1 ; { スタックポインタ }
- ep : dataRange ; { スタック枠の最大を保持する }
-
- inputAdr : dataRange ; { input ファイルバッファ変数アドレス }
- outputAdr : dataRange ; { outputファイルバッファ変数アドレス }
-
-
- (****************************)
- (* 初期設定処理 *)
- (****************************)
- procedure initialize ;
- var cc : codeRange ;
- dc : dataRange ;
- begin
- (*** コードファイルの読み込み ***)
- reset(pcode) ;
- cc := 0 ;
- while not eof(pcode) do
- begin
- read(pcode,code[cc]) ;
- cc := cc + 1
- end ;
-
- (*** 定数ファイルの読み込み ***)
- reset(pconst) ;
- dc := 0 ;
- while not eof(pConst) do
- begin
- read(pConst,store[dc]) ;
- dc := dc + 1
- end ;
-
- (*** レジスタ類初期設定 ***)
- pc := 0 ;
- mp := dc ;
- sp := mp - 1 ;
- ep := mp ;
- np := MaxData ;
-
- (*** バッファ変数アドレス設定 ***)
- inputAdr := mp + 5 ;
- outputAdr := mp + 6
- end {initialize} ;
-
- (****************************)
- (* ランタイムエラーメッセージ出力処理 *)
- (****************************)
- procedure RunErr(errorNum : integer) ;
- begin
- writeln ;
- write('*** [ADDR=',pc-1:1,'] HAPPy Run-time error R',errorNum:1,
- ': 処理打ち切り ***') ;
- goto 9999
- end ;
-
- (****************************)
- (* 解釈実行処理 *)
- (****************************)
- procedure interpret ;
- var run : Boolean ;
- trace : Boolean ;
- width : integer ;
- ad : dataRange1 ;
- leng : integer ;
- i : integer ;
- low,high : integer ;
- s : setType ;
-
- (**** 基準アドレス取得関数 ****)
- function base(p : pType) : dataRange ;
- var ad : dataRange ;
- i : pType ;
- begin
- if p = 0 then base := mp
- else begin
- ad := mp ;
- for i:=1 to p do ad := store[ad+1].va ; { 静鎖をたどる }
- base := ad
- end
- end {base} ;
-
- (***** 文字列比較関数 *****)
- (* 関数値 : < 0 ・・・ 小さい 0 ・・・ 等しい >0 ・・・ 大きい *)
- function cmpStr(length : integer) : integer ;
- label 9 ;
- var i : integer ;
- diff : integer ;
- begin
- for i:=0 to length-1 do
- begin
- diff := ord(store[store[sp ].va+i].vc)
- - ord(store[store[sp+1].va+i].vc) ;
- if diff <> 0 then goto 9
- end ;
- 9 :
- cmpStr := diff
- end {cmpStr} ;
-
- begin {interpret}
- run := true ;
- trace := false ;
-
- while run do { stp 命令を実行するまで }
- with code[pc] do
- begin
- if trace then { トレースが必要な時 }
- writeln(pc:4,':',ord(op):4,
- ' mp=',mp:4,' ep=',ep:4,' np=',np:4,
- ' store[',sp:4,']=',store[sp].vi) ;
- { ↑ sp=-1 の時は誤り 要検討 }
-
- pc := pc + 1 ; { 命令をフェッチ後にプログラムカウンタを更新する }
-
- case op of
-
- iABI : (* absolute integers *)
- store[sp].vi := abs(store[sp].vi) ;
-
- iABR : (* absolute reals *)
- store[sp].vr := abs(store[sp].vr) ;
-
- iADI : begin (* add integers *)
- sp := sp - 1 ;
- store[sp].vi := store[sp].vi + store[sp+1].vi
- end ;
-
- iADR : begin (* add reals *)
- sp := sp - 1 ;
- store[sp].vr := store[sp].vr + store[sp+1].vr
- end ;
-
- iAND : begin (* and operator *)
- sp := sp - 1 ;
- store[sp].vb := store[sp].vb and store[sp+1].vb
- end ;
-
- iATN : (* arctan standard function *)
- store[sp].vr := arctan(store[sp].vr) ;
-
- iBAS : begin (* load base mark address *)
- sp := sp + 1 ;
- store[sp].va := base(p)
- end ;
-
- iCHK : (* check value between bounds *)
- if (store[sp].vi < store[q ].vi) or
- (store[sp].vi > store[q+1].vi) then RunErr(p) ;
-
- iCHR : begin (* chr standard function *)
- if (0 > store[sp].vi) or (255 < store[sp].vi) then
- RunErr(37) ; { 引数値異常 }
- store[sp].vc := chr(store[sp].vi)
- end ;
-
- iCKA : (* check address *)
- if store[sp].va = NilValue then RunErr(3) { nil }
- else if store[sp].va < np then RunErr(4) ; { 不定 }
-
- iCKS : (* check set *)
- if not (store[sp].vs <= store[q].vs) then RunErr(p) ;
-
- iCOS : (* cos standard function *)
- store[sp].vr := cos(store[sp].vr) ;
-
- iCUI : begin (* call user procedure indirect *)
- sp := sp - 1 ;
- mp := sp - (p + 4) ;
- store[mp+4].vp := pc ;
- pc := store[sp+1].vp
- end ;
-
- iCUP : begin (* call user procedure *)
- mp := sp - (p+4) ;
- store[mp+4].vp := pc ;
- pc := q
- end ;
-
- iDEC : (* decrement *)
- case p of
- DatAd : store[sp].va := store[sp].va - q ;
- Inte : store[sp].vi := store[sp].vi - q ;
- Bool : store[sp].vb := false ; { 偽以外になることはない }
- Chars : store[sp].vc := chr(ord(store[sp].vc) - q)
- end ;
-
- iDIF : begin (* difference set *)
- sp := sp - 1 ;
- store[sp].vs := store[sp].vs - store[sp+1].vs
- end ;
-
- iDIS : begin (* dispose standard procedure *)
- ad := store[sp].va ;
- if ad = NilValue then RunErr(23) ; { 引数の値がnil }
- if np <= ad then
- begin
- if ad = np then np := np + q { 最も最近にnewされた時のみ }
- end
- else RunErr(24) { 引数の値が不定 }
- end ;
-
- iDVI : begin (* divide integers *)
- if store[sp].vi = 0 then RunErr(45) ; { div演算子 0除算 }
- sp := sp - 1 ;
- store[sp].vi := store[sp].vi div store[sp+1].vi
- end ;
-
- iDVR : begin (* divide reals *)
- if store[sp].vr = 0.0 then RunErr(44); { / 演算子 0除算 }
- sp := sp - 1 ;
- store[sp].vr := store[sp].vr / store[sp+1].vr
- end ;
-
- iEJP : begin (* extra block jump *)
- ad := base(p) ;
- while mp <> ad do { スタックの枠を解放 }
- begin
- sp := mp - 1 ;
- ep := store[mp+3].va ;
- mp := store[mp+2].va { 動鎖 }
- end ;
- pc := q
- end ;
-
- iENT : begin (* enter procedure or function *)
- if mp + p + q -1 > maxData then RunErr(122) ;
- sp := mp + q - 1 ;
- ep := sp + p ;
- if ep >= np then RunErr(122) { スタック用メモリ不足 }
- end ;
-
- iEOF : begin (* eof standard function *)
- sp := sp + 1 ;
- if p = 0 then store[sp].vb := eof(input)
- else store[sp].vb := eof(output) { 常に真 }
- end ;
-
- iEOL : begin (* eoln standard function *)
- sp := sp + 1 ;
- if p = 0 then store[sp].vb := eoln(input)
- else RunErr(42) { outputは常にeofが真だから誤り }
- { 本物はバグのため誤りにならない}
- end ;
-
- iEQU : begin (* equal operator *)
- sp := sp - 1 ;
- case p of
- DatAd : store[sp].vb := store[sp].va = store[sp+1].va ;
- Inte : store[sp].vb := store[sp].vi = store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr = store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb = store[sp+1].vb ;
- Sets : store[sp].vb := store[sp].vs = store[sp+1].vs ;
- Multi : store[sp].vb := cmpStr(q) = 0 ;
- Chars : store[sp].vb := store[sp].vc = store[sp+1].vc
- end
- end ;
-
- iEXP : (* exp standard function *)
- store[sp].vr := exp(store[sp].vr) ;
-
- iFJP : begin (* jump on false *)
- if not store[sp].vb then pc := q ;
- sp := sp - 1
- end ;
-
- iFLO : (* float integer to real on sp-1 *)
- store[sp-1].vr := store[sp-1].vi ;
-
- iFLT : (* float integer to real *)
- store[sp].vr := store[sp].vi ;
-
- iGEQ : begin (* grater than equal operator *)
- sp := sp - 1 ;
- case p of
- Inte : store[sp].vb := store[sp].vi >= store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr >= store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb >= store[sp+1].vb ;
- Sets : store[sp].vb := store[sp].vs >= store[sp+1].vs ;
- Multi : store[sp].vb := cmpStr(q) >= 0 ;
- Chars : store[sp].vb := store[sp].vc >= store[sp+1].vc
- end
- end ;
-
- iGET : ; (* get from not text *)
- { input,output以外のファイルはサポートしないので
- この命令は出現しない }
-
- iGRT : begin (* grater than operator *)
- sp := sp - 1 ;
- case p of
- Inte : store[sp].vb := store[sp].vi > store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr > store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb > store[sp+1].vb ;
- Multi : store[sp].vb := cmpStr(q) > 0 ;
- Chars : store[sp].vb := store[sp].vc > store[sp+1].vc
- end
- end ;
-
- iINC : (* increment *)
- case p of
- DatAd : store[sp].va := store[sp].va + q ;
- Inte : store[sp].vi := store[sp].vi + q ;
- Bool : store[sp].vb := true ; { 真以外はありえない }
- Chars : store[sp].vc := chr(ord(store[sp].vc) + q)
- end ;
-
- iIND : (* indexed fetch *)
- store[sp] := store[store[sp].va+q] ;
-
- iINN : begin (* in operator *)
- sp := sp - 1 ;
- store[sp].vb := store[sp].vi in store[sp+1].vs
- end ;
-
- iINT : begin (* intersection set *)
- sp := sp - 1 ;
- store[sp].vs := store[sp].vs * store[sp+1].vs
- end ;
-
- iIOR : begin (* or operator *)
- sp := sp - 1 ;
- store[sp].vb := store[sp].vb or store[sp+1].vb
- end ;
-
- iIXA : begin (* indeced address *)
- sp := sp - 1 ;
- store[sp].va := store[sp].va +
- store[q+1].vi * (store[sp+1].vi - store[q].vi)
- end ;
-
- iLAO , (* load base-level address *)
- iLCA : begin (* load address of constant *)
- sp := sp + 1 ;
- store[sp].va := q
- end ;
-
- iLAP : begin (* load address of procedure *)
- sp := sp + 1 ;
- store[sp].vp := q
- end ;
-
- iLDA : begin (* load level p address *)
- sp := sp + 1 ;
- store[sp].va := base(p) + q
- end ;
-
- iLDC : begin (* load constant *)
- sp := sp + 1 ;
- case p of
- Nils : store[sp].va := NilValue ; { nil値ロード }
- Inte : store[sp].vi := q ;
- Reals : store[sp].vr := store[q].vr ;
- Bool : store[sp].vb := q = 1 ;
- Sets : store[sp].vs := store[q].vs ;
- Chars : store[sp].vc := chr(q)
- end
- end ;
-
- iLDO : begin (* load contents of base-level address *)
- sp := sp + 1 ;
- if (p = Chars) and (q = inputAdr) then { input^に対する }
- begin { ldoc命令 }
- store[inputAdr].vc := input^ ;
- store[sp ].vc := input^
- end
- else store[sp] := store[q]
- { それ以外のldo命令はデータタイプ関係なく丸ごとロード }
- end ;
-
- iLEQ : begin (* less than equal operator *)
- sp := sp - 1 ;
- case p of
- Inte : store[sp].vb := store[sp].vi <= store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr <= store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb <= store[sp+1].vb ;
- Sets : store[sp].vb := store[sp].vs <= store[sp+1].vs ;
- Multi : store[sp].vb := cmpStr(q) <= 0 ;
- Chars : store[sp].vb := store[sp].vc <= store[sp+1].vc
- end
- end ;
-
- iLES : begin (* less than operator *)
- sp := sp - 1 ;
- case p of
- Inte : store[sp].vb := store[sp].vi < store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr < store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb < store[sp+1].vb ;
- Multi : store[sp].vb := cmpStr(q) < 0 ;
- Chars : store[sp].vb := store[sp].vc < store[sp+1].vc
- end
- end ;
-
- iLOD : begin (* load contents of address at level p *)
- sp := sp + 1 ;
- store[sp] := store[base(p)+q]
- end ;
-
- iLOG : begin (* ln standard function *)
- if store[sp].vr <= 0.0 then RunErr(33) ; { 引数が0以下 }
- store[sp].vr := ln(store[sp].vr)
- end ;
-
- iMMS : begin (* make multiple set *)
- sp := sp - 1 ;
- if p <= 1 then { p in [0,1] }
- begin
- low := store[sp ].vi ;
- high := store[sp+1].vi
- end
- else { p in [2,3] }
- begin
- low := store[sp+1].vi ;
- high := store[sp ].vi
- end ;
- if p in [1,3] then { -d デバッグオプションコンパイル }
- if ( low <= high) and { 要素が作られる条件 }
- ((low < SetLow) or (high > SetHigh)) then
- RunErr(112) ; { 集合要素順序数範囲外 }
- s := [] ;
- for i:=low to high do s := s + [i] ;
- store[sp].vs := s
- end ;
-
- iMOD : begin (* modulo operator *)
- if store[sp].vi <= 0 then RunErr(46) ; { 被演算子 <=0 }
- sp := sp - 1 ;
- store[sp].vi := store[sp].vi mod store[sp+1].vi
- end ;
-
- iMOV : begin (* move *)
- if p = 1 then
- for i:=0 to q-1 do
- store[store[sp-1].va+i] := store[store[sp ].va+i]
- else { p = 2 }
- for i:=0 to q -1 do
- store[store[sp ].va+i] := store[store[sp-1].va+i] ;
- sp := sp - 2
- end ;
-
- iMPI : begin (* mulutiple integers *)
- sp := sp - 1 ;
- store[sp].vi := store[sp].vi * store[sp+1].vi
- end ;
-
- iMPR : begin (* mulutiple reals *)
- sp := sp - 1 ;
- store[sp].vr := store[sp].vr * store[sp+1].vr
- end ;
-
- iMSI : begin (* mark stack indirect *)
- sp := sp - 1 ;
- store[sp+2].va := store[sp+1].va ;
- store[sp+3].va := mp ;
- store[sp+4].va := ep ;
- sp := sp + 5
- end ;
-
- iMST : begin (* mark stack *)
- store[sp+2].va := base(p) ; { 静鎖 }
- store[sp+3].va := mp ; { 動鎖 }
- store[sp+4].va := ep ;
- sp := sp + 5
- end ;
-
- iNEQ : begin (* not equal operator *)
- sp := sp - 1 ;
- case p of
- Datad : store[sp].vb := store[sp].va <> store[sp+1].va ;
- Inte : store[sp].vb := store[sp].vi <> store[sp+1].vi ;
- Reals : store[sp].vb := store[sp].vr <> store[sp+1].vr ;
- Bool : store[sp].vb := store[sp].vb <> store[sp+1].vb ;
- Sets : store[sp].vb := store[sp].vs <> store[sp+1].vs ;
- Multi : store[sp].vb := cmpStr(q) <> 0 ;
- Chars : store[sp].vb := store[sp].vc <> store[sp+1].vc
- end
- end ;
-
- iNEW : begin (* new standard procedure *)
- np := np - q ; { q : 割当要求量 }
- if np <= ep then RunErr(121) ; { メモリ不足で割り付け不能 }
- store[store[sp].va].va := np ;
- sp := sp - 1
- end ;
-
- iNGI : (* negative integers *)
- store[sp].vi := -store[sp].vi ;
-
- iNGR : (* negative reals *)
- store[sp].vr := -store[sp].vr ;
-
- iNOT : (* not operator *)
- store[sp].vb := not store[sp].vb ;
-
- iNXT : (* next to *)
- case p of
- Inte : store[mp+q].vi := succ(store[mp+q].vi) ;
- Bool : store[mp+q].vb := succ(store[mp+q].vb) ;
- Chars : store[mp+q].vc := succ(store[mp+q].vc)
- end ;
-
- iNXD : (* next downto *)
- case p of
- Inte : store[mp+q].vi := pred(store[mp+q].vi) ;
- Bool : store[mp+q].vb := pred(store[mp+q].vb) ;
- Chars : store[mp+q].vc := pred(store[mp+q].vc)
- end ;
-
- iODD : (* odd standard function *)
- store[sp].vb := odd(store[sp].vi) ;
-
- iORD : (* ord standard function *)
- case p of
- Chars : store[sp].vi := ord(store[sp].vc) ; { ordc }
- Bool : store[sp].vi := ord(store[sp].vb) { ordb }
- end ;
-
- iPGE : (* page standard procedure *)
- if p = 0 then RunErr(9) { inputは生成モードでない }
- else page(output) ;
-
- iPUT : ; (* put from not text *)
- { input,output以外のファイルはサポートしないので
- この命令は出現しない }
-
- iRDC : begin (* read character *)
- if p = 1 then RunErr(14) ; { outputは検査モードでない }
- read(input,store[store[sp].va].vc) ;
- store[inputAdr].vc := input^ ;
- sp := sp - 1
- end ;
-
- iRDI : begin (* read integer *)
- if p = 1 then RunErr(14) ; { outputは検査モードでない }
- read(input,store[store[sp].va].vi) ;
- store[inputAdr].vc := input^ ;
- sp := sp - 1
- end ;
-
- iRDR : begin (* read real *)
- if p = 1 then RunErr(14) ; { outputは検査モードでない }
- read(input,store[store[sp].va].vr) ;
- store[inputAdr].vc := input^ ;
- sp := sp - 1
- end ;
-
- iRET : begin (* return from procedure or function *)
- if p = Proc then sp := mp - 1 { 手続きの戻り }
- else sp := mp ; { 関数 の戻り }
- pc := store[mp+4].vp ;
- ep := store[mp+3].va ;
- mp := store[mp+2].va
- end ;
-
- iRLN : (* readln standard procedure *)
- if p = 1 then RunErr(14) { outputは検査モードでない }
- else readln(input) ;
-
- iROU : (* round standard function *)
- store[sp].vi := round(store[sp].vr) ;
-
- iRST : ; (* reset for not text *)
- { input,output以外のファイルはサポートしないので
- この命令は出現しない }
-
- iRWT : ; (* rewrite for not text *)
- { input,output以外のファイルはサポートしないので
- この命令は出現しない }
-
- iSBI : begin (* subtract integers *)
- sp := sp - 1 ;
- store[sp].vi := store[sp].vi - store[sp+1].vi
- end ;
-
- iSBR : begin (* subtract reals *)
- sp := sp - 1 ;
- store[sp].vr := store[sp].vr - store[sp+1].vr
- end ;
-
- iSGS : (* create singleton set *)
- store[sp].vs := [store[sp].vi] ;
-
- iSIN : (* sin standard function *)
- store[sp].vr := sin(store[sp].vr) ;
-
- iSQI : (* square integers *)
- store[sp].vi := sqr(store[sp].vi) ;
-
- iSQR : (* square reals *)
- store[sp].vr := sqr(store[sp].vr) ;
-
- iSQT : begin (* sqrt standard function *)
- if store[sp].vr < 0.0 then RunErr(34) ; { 引数が負 }
- store[sp].vr := sqrt(store[sp].vr)
- end ;
-
- iSRO : begin (* store at base-level address *)
- store[q] := store[sp] ;
- sp := sp - 1
- end ;
-
- iSTO : begin (* store indirect *)
- store[store[sp-1].va] := store[sp] ;
- sp := sp - 2
- end ;
-
- iSTP : (* stop *)
- run := false ;
-
- iSTR : begin (* store contents at address at level p *)
- store[base(p)+q] := store[sp] ;
- sp := sp - 1
- end ;
-
- iTGT : begin (* get from text *)
- if p = 1 then RunErr(14) ; { outputは検査モードでない }
- get(input) ;
- store[inputAdr].vc := input^
- end ;
-
- iTPT : begin (* put from text *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない }
- output^ := store[outputAdr].vc ;
- put(output)
- end ;
-
- iTRA : (* trace of execution *)
- trace := p = 1 ;
-
- iTRC : (* trunc standard function *)
- store[sp].vi := trunc(store[sp].vr) ;
-
- iTRS : (* reset for text file *)
- RunErr(81) ; { input,outputファイルに対してresetできない }
-
- iTRW : (* rewrite for text file *)
- RunErr(82) ; { input,outputファイルに対してrewriteできない }
-
- iUJC : (* check uncondition jump *)
- RunErr(51) ; { case文の選択式の値に合致する選択定数がない }
-
- iUJP : (* uncondition jump *)
- pc := q ;
-
- iUNI : begin (* union set *)
- sp := sp - 1 ;
- store[sp].vs := store[sp].vs + store[sp+1].vs
- end ;
-
- iWLN : (* writeln standard procedure *)
- if p = 0 then RunErr(9) { inputは生成モードでない }
- else writeln(output) ;
-
- iWRB : begin (* write boolean *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない } write(output,store[sp-1].vb:store[sp].vi) ;
- sp := sp - 2
- end ;
-
- iWRC : begin (* write char *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない }
- write(output,store[sp-1].vc:store[sp].vi) ;
- sp := sp -2
- end ;
-
- iWRF : begin (* write real fix *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない }
- write(output,store[sp-2].vr:store[sp-1].vi:store[sp].vi) ;
- sp := sp - 3
- end ;
-
- iWRI : begin (* write integer *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない }
- write(output,store[sp-1].vi:store[sp].vi) ;
- sp := sp - 2
- end ;
-
- iWRR : begin (* write real *)
- if p = 0 then RunErr(9) ; { inputは生成モードでない }
- write(output,store[sp-1].vr:store[sp].vi) ;
- sp := sp - 2
- end ;
-
- iWRS : begin (* write string *)
- if p = 2 then RunErr(9) ; { inputは生成モードでない }
- { p = 2 は 正確にはoutput以外のファイルの意味 }
- width := store[sp].vi ;
- ad := store[sp-1].va ;
- leng := q ;
- if width > leng then write(output,' ':width-leng)
- else leng := width ;
- for i:=0 to leng-1 do write(output,store[ad+i].vc) ;
- sp := sp - 2
- end ;
-
- iXJP : begin (* indexed jump *)
- pc := pc + store[sp].vi ;
- sp := sp - 1
- end
-
- end {case op}
- end {with code[pc]}
- end {interpret} ;
-
- (****************************)
- (* メイン処理 *)
- (****************************)
- begin
- initialize ; { 初期設定 }
- interpret ; { 解釈実行 }
- 9999:
- end.